﻿using System;
using System.Text;
using System.Security.Cryptography;

namespace MSL.Utility.Security
{
    /// <summary> 
    /// RSA加密解密及RSA签名和验证
    /// </summary> 
    public class RSACryption
    {
        #region RSA 加密解密

        /// <summary>
        /// RSA 的密钥产生 产生私钥 和公钥 
        /// </summary>
        /// <param name="xmlKeys"></param>
        /// <param name="xmlPublicKey"></param>
        public void RSAKey(out string xmlKeys, out string xmlPublicKey)
        {
            System.Security.Cryptography.RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
            xmlKeys = rsaProvider.ToXmlString(true);
            xmlPublicKey = rsaProvider.ToXmlString(false);
        }

        /// <summary>
        /// RSA的加密函数 说明KEY必须是XML的行式,返回的是字符串  加密方式有 长度 限制的
        /// </summary>
        /// <param name="xmlPublicKey">公钥</param>
        /// <param name="input">要加密的字符串</param>
        /// <returns></returns>
        public string RSAEncrypt(string xmlPublicKey, string input)
        {
            byte[] plainTextBArray;
            byte[] cypherTextBArray;
            string result;
            RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
            rsaProvider.FromXmlString(xmlPublicKey);
            plainTextBArray = (new UnicodeEncoding()).GetBytes(input);
            cypherTextBArray = rsaProvider.Encrypt(plainTextBArray, false);
            result = System.Convert.ToBase64String(cypherTextBArray);
            return result;

        }

        /// <summary>
        /// RSA的加密函数 byte[]
        /// </summary>
        /// <param name="xmlPublicKey"></param>
        /// <param name="encryptString"></param>
        /// <returns></returns>
        public string RSAEncrypt(string xmlPublicKey, byte[] encryptString)
        {
            byte[] cypherTextBArray;
            string result;
            RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
            rsaProvider.FromXmlString(xmlPublicKey);
            cypherTextBArray = rsaProvider.Encrypt(encryptString, false);
            result = System.Convert.ToBase64String(cypherTextBArray);
            return result;
        }

        /// <summary>
        /// RSA的解密函数
        /// </summary>
        /// <param name="xmlPrivateKey"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public string RSADecrypt(string xmlPrivateKey, string input)
        {
            byte[] plainTextBArray;
            byte[] dypherTextBArray;
            string result;
            System.Security.Cryptography.RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
            rsaProvider.FromXmlString(xmlPrivateKey);
            plainTextBArray = System.Convert.FromBase64String(input);
            dypherTextBArray = rsaProvider.Decrypt(plainTextBArray, false);
            result = (new UnicodeEncoding()).GetString(dypherTextBArray);
            return result;
        }

        /// <summary>
        /// RSA的解密函数 byte
        /// </summary>
        /// <param name="xmlPrivateKey"></param>
        /// <param name="decryptString"></param>
        /// <returns></returns>
        public string RSADecrypt(string xmlPrivateKey, byte[] decryptString)
        {
            byte[] dypherTextBArray;
            string result;
            System.Security.Cryptography.RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
            rsaProvider.FromXmlString(xmlPrivateKey);
            dypherTextBArray = rsaProvider.Decrypt(decryptString, false);
            result = (new UnicodeEncoding()).GetString(dypherTextBArray);
            return result;

        }

        #endregion

        #region RSA数字签名

        /// <summary>
        /// 获取Hash描述表 
        /// </summary>
        /// <param name="input"></param>
        /// <param name="hashData"></param>
        /// <returns></returns>
        public bool GetHash(string input, ref byte[] hashData)
        {
            //从字符串中取得Hash描述 
            byte[] buffer;
            System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.HashAlgorithm.Create("MD5");
            buffer = System.Text.Encoding.GetEncoding("GB2312").GetBytes(input);
            hashData = MD5.ComputeHash(buffer);

            return true;
        }

        /// <summary>
        /// 获取Hash描述表 
        /// </summary>
        /// <param name="input"></param>
        /// <param name="strHashData"></param>
        /// <returns></returns>
        public bool GetHash(string input, ref string hashData)
        {

            //从字符串中取得Hash描述 
            byte[] buffer;
            byte[] hash;
            System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.HashAlgorithm.Create("MD5");
            buffer = System.Text.Encoding.GetEncoding("GB2312").GetBytes(input);
            hash = MD5.ComputeHash(buffer);

            hashData = System.Convert.ToBase64String(hash);
            return true;

        }

        /// <summary>
        /// 获取Hash描述表 
        /// </summary>
        /// <param name="objFile"></param>
        /// <param name="hashData"></param>
        /// <returns></returns>
        public bool GetHash(System.IO.FileStream objFile, ref byte[] hashData)
        {

            //从文件中取得Hash描述 
            System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.HashAlgorithm.Create("MD5");
            hashData = MD5.ComputeHash(objFile);
            objFile.Close();

            return true;

        }

        /// <summary>
        /// 获取Hash描述表
        /// </summary>
        /// <param name="objFile"></param>
        /// <param name="strHashData"></param>
        /// <returns></returns>
        public bool GetHash(System.IO.FileStream objFile, ref string hashData)
        {
            //从文件中取得Hash描述 
            byte[] hash;
            System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.HashAlgorithm.Create("MD5");
            hash = MD5.ComputeHash(objFile);
            objFile.Close();

            hashData = System.Convert.ToBase64String(hash);

            return true;

        }

        /// <summary>
        /// RSA签名 
        /// </summary>
        /// <param name="privateKey"></param>
        /// <param name="hashbyteSignature"></param>
        /// <param name="encryptedSignatureData"></param>
        /// <returns></returns>
        public bool SignatureFormatter(string privateKey, byte[] hashbyteSignature, ref byte[] encryptedSignatureData)
        {

            System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();

            RSA.FromXmlString(privateKey);
            System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.RSAPKCS1SignatureFormatter(RSA);
            //设置签名的算法为MD5 
            RSAFormatter.SetHashAlgorithm("MD5");
            //执行签名 
            encryptedSignatureData = RSAFormatter.CreateSignature(hashbyteSignature);

            return true;

        }

        /// <summary>
        /// RSA签名 
        /// </summary>
        /// <param name="privateKey"></param>
        /// <param name="hashbyteSignature"></param>
        /// <param name="m_strEncryptedSignatureData"></param>
        /// <returns></returns>
        public bool SignatureFormatter(string privateKey, byte[] hashbyteSignature, ref string m_strEncryptedSignatureData)
        {

            byte[] encryptedSignatureData;

            System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
            RSA.FromXmlString(privateKey);
            System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.RSAPKCS1SignatureFormatter(RSA);
            //设置签名的算法为MD5 
            RSAFormatter.SetHashAlgorithm("MD5");
            //执行签名 
            encryptedSignatureData = RSAFormatter.CreateSignature(hashbyteSignature);

            m_strEncryptedSignatureData = System.Convert.ToBase64String(encryptedSignatureData);

            return true;

        }

        /// <summary>
        /// RSA签名 
        /// </summary>
        /// <param name="privateKey"></param>
        /// <param name="m_strHashbyteSignature"></param>
        /// <param name="encryptedSignatureData"></param>
        /// <returns></returns>
        public bool SignatureFormatter(string privateKey, string hashbyteSignature, ref byte[] encryptedSignatureData)
        {

            byte[] hashByte;

            hashByte = System.Convert.FromBase64String(hashbyteSignature);
            System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();

            RSA.FromXmlString(privateKey);
            System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.RSAPKCS1SignatureFormatter(RSA);
            //设置签名的算法为MD5 
            RSAFormatter.SetHashAlgorithm("MD5");
            //执行签名 
            encryptedSignatureData = RSAFormatter.CreateSignature(hashByte);

            return true;

        }

        /// <summary>
        /// RSA签名 
        /// </summary>
        /// <param name="privateKey"></param>
        /// <param name="m_strHashbyteSignature"></param>
        /// <param name="m_strEncryptedSignatureData"></param>
        /// <returns></returns>
        public bool SignatureFormatter(string privateKey, string hashbyteSignature, ref string encryptedSignatureData)
        {

            byte[] hashByte;
            byte[] encryptedByte;

            hashByte = System.Convert.FromBase64String(hashbyteSignature);
            System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();

            RSA.FromXmlString(privateKey);
            System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.RSAPKCS1SignatureFormatter(RSA);
            //设置签名的算法为MD5 
            RSAFormatter.SetHashAlgorithm("MD5");
            //执行签名 
            encryptedByte = RSAFormatter.CreateSignature(hashByte);

            encryptedSignatureData = System.Convert.ToBase64String(encryptedByte);

            return true;

        }
        /// <summary>
        /// RSA 签名验证
        /// </summary>
        /// <param name="publicKey"></param>
        /// <param name="hashbyteDeformatter"></param>
        /// <param name="deformatterData"></param>
        /// <returns></returns>
        public bool SignatureDeformatter(string publicKey, byte[] hashbyteDeformatter, byte[] deformatterData)
        {

            System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();

            RSA.FromXmlString(publicKey);
            System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA);
            //指定解密的时候HASH算法为MD5 
            RSADeformatter.SetHashAlgorithm("MD5");

            if (RSADeformatter.VerifySignature(hashbyteDeformatter, deformatterData))
            {
                return true;
            }
            else
            {
                return false;
            }

        }

        public bool SignatureDeformatter(string publicKey, string p_strHashbyteDeformatter, byte[] deformatterData)
        {

            byte[] hashbyteDeformatter = System.Convert.FromBase64String(p_strHashbyteDeformatter);

            System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();

            RSA.FromXmlString(publicKey);
            System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA);
            //指定解密的时候HASH算法为MD5 
            RSADeformatter.SetHashAlgorithm("MD5");

            if (RSADeformatter.VerifySignature(hashbyteDeformatter, deformatterData))
            {
                return true;
            }
            else
            {
                return false;
            }

        }

        public bool SignatureDeformatter(string publicKey, byte[] hashbyteDeformatter, string p_strDeformatterData)
        {

            byte[] deformatterData;

            System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();

            RSA.FromXmlString(publicKey);
            System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA);
            //指定解密的时候HASH算法为MD5 
            RSADeformatter.SetHashAlgorithm("MD5");

            deformatterData = System.Convert.FromBase64String(p_strDeformatterData);

            if (RSADeformatter.VerifySignature(hashbyteDeformatter, deformatterData))
            {
                return true;
            }
            else
            {
                return false;
            }

        }

        public bool SignatureDeformatter(string publicKey, string p_strHashbyteDeformatter, string p_strDeformatterData)
        {

            byte[] deformatterData;
            byte[] hashbyteDeformatter;

            hashbyteDeformatter = System.Convert.FromBase64String(p_strHashbyteDeformatter);
            System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();

            RSA.FromXmlString(publicKey);
            System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA);
            //指定解密的时候HASH算法为MD5 
            RSADeformatter.SetHashAlgorithm("MD5");

            deformatterData = System.Convert.FromBase64String(p_strDeformatterData);

            if (RSADeformatter.VerifySignature(hashbyteDeformatter, deformatterData))
            {
                return true;
            }
            else
            {
                return false;
            }

        }

        #endregion

        #region IDisposable 成员

        private RSACryption()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }
        ~RSACryption()
        {
            Dispose();
        }

        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}
